/*  tBookShelf: TextPlugin
    (C) 2007  TvN (Volodymyr Tarasenko), e-mail: tvntsr@yahoo.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#ifndef TEXT_READER_TEXT_PLUGIN_HPP
#define TEXT_READER_TEXT_PLUGIN_HPP

#include <string>
#include <memory>
#include <stdexcept>

#include "LuaParser.hpp"
#include "PageManager.hpp"
#include "StreamManager.hpp"

#include "Utils/Fonts/FontManager.hpp"

struct BookMark
{
    size_t file_pos;
    size_t page_num;

};

// Main class for plugin implementation
class TextReader
{
public:
    TextReader()
        : text(), smanager(0), fmanager(0), cparser(0), cache(0), 
          page_orient(Portrait)
    {}

    ~TextReader()
    {
        if (smanager)
            delete smanager;

        if (fmanager)
            delete fmanager;

        if (cparser)
            delete cparser;
    }

    void registerStreamManager(std::auto_ptr<StreamManager>& sman)
    {
        if (smanager)
            delete smanager;

        smanager = sman.release();
    }

    void registerFontManager(std::auto_ptr<FontManager>& fman)
    {
        if (fmanager)
            delete fmanager;

        fmanager = fman.release();
    }

    void registerConfigManager(std::auto_ptr<ConfigParser>& cfg)
    {
        if (cparser)
            delete cparser;

        cparser = cfg.release();
    }
    
    void registerCacheManager(std::auto_ptr<PageCacheManager>& cman)
    {
        if (cache)
            delete cache;

        cache = cman.release();
    }

    const std::string& textFileName() const
    {
        return text;
    }

    StreamManager& streamManager()
    {
        if (smanager == 0)
            throw std::runtime_error("StreamManager unregistered");

        return *smanager;
    }

    const StreamManager& streamManager() const
    {
        if (smanager == 0)
            throw std::runtime_error("StreamManager unregistered");

        return *smanager;
    }

    ConfigParser& configManager()
    {
        if (cparser == 0)
            throw std::runtime_error("ConfigParser unregistered");

        return *cparser;
    }

    const ConfigParser& configManager() const
    {
        if (cparser == 0)
            throw std::runtime_error("ConfigParser unregistered");

        return *cparser;
    }

    FontManager& fontManager()
    {
        if (fmanager == 0)
            throw std::runtime_error("FontManager unregistered");

        return *fmanager;
    }

    const FontManager& fontManager() const
    {
        if (fmanager == 0)
            throw std::runtime_error("FontManager unregistered");

        return *fmanager;
    }

    PageCacheManager& cacheManager()
    {
        if (cache == 0)
            throw std::runtime_error("PageCacheManager unregistered");

        return *cache;
    }

    const PageCacheManager& cacheManager() const
    {
        if (cache == 0)
            throw std::runtime_error("PageCacheManager unregistered");
        
        return *cache;
    }

    // Return page count
    int open(const std::string& file);
    void destroyPages()
    {
        cacheManager().destroyPages();
    }

    bool convertStrToWstr(const std::string&, wchar_t**);

    void preRenderPages(size_t start, size_t count);
    void renderPage(Page* page, bool imitate = false);

    void renderArea(Page* page, 
                    char* buff,
                    const Point& start,
                    const Point& end);

    void changeSpaces(std::string& p, const TextStyle& style);
    size_t getPageNumber(size_t pos, PageOrientation orient);
    
    void getPageText(const size_t    num,
                     PageOrientation orient,
                     const size_t    offset, 
                     std::string&    to,
                     const size_t    chars);


    void setPageOrientation(const PageOrientation& to);

    int getPageCount() const
    {
        return cacheManager().pageCount();
    }

    PageOrientation getPageOrientation()
    {
        return page_orient;
    }
private:
    void copyPageBuffer(Page*, char* buff, const Point& start, const Point& end);

private:
    // disable copying
    TextReader(const TextReader&);
    TextReader& operator=(const TextReader&);

private:
    std::string    text;

    StreamManager* smanager;
    FontManager*   fmanager; 
    ConfigParser*  cparser;

    PageCacheManager* cache;

    PageOrientation  page_orient;
};


#endif //TEXT_READER_TEXT_PLUGIN_HPP
